package cn.livingCloud.service.impl;

import cn.livingCloud.context.Config;
import cn.livingCloud.entity.core.JobInfo;
import cn.livingCloud.entity.core.PushGroup;
import cn.livingCloud.repository.PushGroupMapper;
import cn.livingCloud.service.QuartzJobService;
import cn.livingCloud.service.impl.operation.DownloadImageJob;
import org.quartz.*;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by 唐旭 on 2016/6/23.
 */
@Service
public class QuartzJobServiceImpl implements QuartzJobService, InitializingBean, DisposableBean {
    public static final String DATA_NAME = "JobInfo";

    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;
    @Autowired
    private PushGroupMapper pushGroupMapper;

    @Override
    public void addJob(JobInfo jobInfo) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        //这里获取任务信息数据
        TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getJobName(), jobInfo.getJobGroup());
        //获取trigger，即在spring配置文件中定义的 bean id="myTrigger"
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        //不存在，创建一个
        if (null == trigger) {
            createJob(jobInfo);
        } else {
            refreshJob(jobInfo, trigger);

        }
    }

    /**
     * 刷新一个job
     *
     * @param pushGroup 推送分组
     * @param trigger   定时触发器
     * @throws SchedulerException
     */
    private void refreshJob(JobInfo pushGroup, CronTrigger trigger) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        TriggerKey triggerKey = TriggerKey.triggerKey(pushGroup.getJobName(), pushGroup.getJobGroup());

        // Trigger已存在，那么更新相应的定时设置
        //表达式调度构建器
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(pushGroup.getCronExpression());
        //按新的cronExpression表达式重新构建trigger
        trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
        //按新的trigger重新设置job执行
        scheduler.rescheduleJob(triggerKey, trigger);
    }

    /**
     * 创建一个job
     *
     * @param pushGroup 推送分组
     */
    private void createJob(JobInfo pushGroup) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobDetail jobDetail = JobBuilder.newJob(pushGroup.getClass()).withIdentity(pushGroup.getJobName(), pushGroup.getJobGroup()).build();
        jobDetail.getJobDataMap().put(DATA_NAME, pushGroup);
        //表达式调度构建器
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(pushGroup.getCronExpression());
        //按新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(pushGroup.getJobName(), pushGroup.getJobGroup()).withSchedule(scheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, trigger);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (!Config.ENVIRONMENT.equals("development")) {//开发模式不启用
            List<PushGroup> groupList = pushGroupMapper.selectAllGroup();
            for (PushGroup pushGroup : groupList) {
                addJob(pushGroup);
            }
            addJob(new DownloadImageJob());
        }
    }

    @Override
    public void destroy() throws Exception {
        schedulerFactoryBean.getScheduler().shutdown();
    }
}
